package org.btik.video.server.device.udp2;

import android.graphics.*;
import android.view.SurfaceHolder;
import androidx.annotation.NonNull;
import org.btik.video.server.VideoChannel;

/**
 * @author lustre
 * @since 2023/5/2 21:36
 */
public class MultiSegmentedFramesFrameVideoPainter implements VideoChannel, SurfaceHolder.Callback {

    private final Paint paint = new Paint();

    private SurfaceHolder surfaceHolder;
    Matrix matrix = new Matrix();

    private final byte[] frameBuffer = new byte[64512];

    /**
     * 写入位 也是已有数据的长度
     */
    private int currentIndex = 0;

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        currentIndex = 0;
        this.surfaceHolder = holder;
        // 计算缩放比
        Canvas canvas = holder.lockHardwareCanvas();
        int height = canvas.getHeight();
        int width = canvas.getWidth();
        holder.unlockCanvasAndPost(canvas);
        float sx = width / 480f;
        float sy = height / 320f;
        matrix.setScale(sx, sy);

    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }

    @Override
    public void sendFrame(byte[] frame, int size) {
        if (surfaceHolder == null) {
            return;
        }
        // byte在这里的比较时有符号 需要将 0xff d8 d9强转成byte 再比较
        // 当前判断是为了减少上一次帧 多个块部分丢包带来的影响
        if (frame[0] == (byte) 0xFF && frame[1] == (byte) 0xD8) {
            // 把前面的碎片也显示出来
            if (currentIndex > 0) {
                Canvas canvas = surfaceHolder.lockHardwareCanvas();
                Bitmap bitmap = BitmapFactory.decodeByteArray(frameBuffer, 0, currentIndex);
                canvas.drawBitmap(bitmap, matrix, paint);
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
            System.arraycopy(frame, 0, frameBuffer, 0, size);
            currentIndex = size;
            return;
        }
        System.arraycopy(frame, 0, frameBuffer, currentIndex, size);
        currentIndex += size;
        // 第一个分块一定有 0xFF 0xD8 但最后一个分块 可能只有0xD9 没有0xFF故写入到 buffer里面之后再判断
        if (frameBuffer[currentIndex - 1] == (byte) 0xD9 && frameBuffer[currentIndex - 2] == (byte) 0xFF) {
            Canvas canvas = surfaceHolder.lockHardwareCanvas();
            Bitmap bitmap = BitmapFactory.decodeByteArray(frameBuffer, 0, currentIndex);
            canvas.drawBitmap(bitmap, matrix, paint);
            surfaceHolder.unlockCanvasAndPost(canvas);
            currentIndex = 0;
        }

    }
}
